package gamelogic

import (
	"server_cluster/common/config"
	"server_cluster/common/logger"
	"server_cluster/common/myepoll"
	"server_cluster/common/mysock"
	"server_cluster/common/protoc/pb"
	"server_cluster/logic/game_config"
	"server_cluster/logic/sharemem"

	"google.golang.org/protobuf/proto"
)

var SELF *sharemem.User = nil

func LogErrorMsgCallback(msg string) {
	if !game_config.GetConfig().DevEnv {
		return
	}
	if SELF == nil {
		return
	}
	buf := mysock.Create()
	buf.Command = config.SC_ServerErrorLogNtf
	buf.Session = uint64(SELF.GetUid())
	buf.Code = config.OK
	ntf := &pb.SC_ServerErrorLogNtf{Msg: msg}
	data, _ := proto.Marshal(ntf)
	logger.Debug("[SEND] cmdId: %v, cmdName: %v, msg: %v, uid: %v", config.SC_ServerErrorLogNtf, ntf.ProtoReflect().Descriptor().FullName(), ntf, SELF.GetUid())
	buf.WriteToServer(myepoll.CONN_TYPE_GATE, SELF.GateServerId, data)
}

func Action(conn *myepoll.Conn, buf *mysock.SockBuf, shm_user **sharemem.User) (errno int16) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error("!!! GAME MAIN LOOP PANIC !!!")
			logger.Error("error: %v", err)
			logger.Error("stack: %v", logger.Stack())
			errno = config.SERVER_PANIC
		}
		SELF = nil
	}()

	if buf.Command == config.CS_Login {
		return UserLogin(conn, buf, shm_user)
	}

	uid := int64(buf.Session)
	user, exist := sharemem.GetUserMap()[uid]
	if !exist {
		if buf.Command == config.SS_User_Offline {
			return config.OK
		}
		logger.Error("user not exist, uid: %v", uid)
		return config.SESSION_NOT_FOUND
	}
	*shm_user = user.Shm_user
	SELF = *shm_user

	if SELF != nil {
		logger.SetGlobalValue("uid", SELF.GetUid())
	}
	defer func() {
		logger.ClearGlobalValue("uid")
	}()

	switch buf.Command {
	case config.CSC_Heart:
		return Heart(SELF, buf)
	case config.CS_Logout:
		return UserLogout(SELF, buf)
	case config.SS_User_Offline:
		return Offline(SELF)
	case config.CS_Reconnect:
		return Reconnect(SELF, buf)

	case config.CS_FETCH:
		return UserFetch(SELF, buf)
	case config.CS_SetClientDataReq:
		return SetClientDataReq(SELF, buf)
	case config.CS_GmReq:
		return GmReq(SELF, buf)

	case config.CS_EnterSceneReq:
		return EnterSceneReq(SELF, buf)
	case config.SC_SceneDataResp:
		return SceneDataReq(SELF, buf)
	case config.CS_GadgetInteractReq:
		return GadgetInteractReq(SELF, buf)
	case config.CS_NpcTalkReq:
		return NpcTalkReq(SELF, buf)
	case config.CS_FinishTimelineReq:
		return FinishTimelineReq(SELF, buf)
	case config.CS_GetScenePointReq:
		return GetScenePointReq(SELF, buf)
	case config.CS_SceneDashFightReq:
		return SceneDashFightReq(SELF, buf)

	case config.CS_ItemActionReq:
		return ItemActionReq(SELF, buf)

	case config.CS_ROLE_ACTION:
		return UserRoleAction(SELF, buf)
	case config.CS_RoleTalentUnlockReq:
		return RoleTalentUnlockReq(SELF, buf)
	case config.CS_RoleTalentUpgradeReq:
		return RoleTalentUpgradeReq(SELF, buf)

	case config.CS_EquipUpgradeReq:
		return EquipUpgradeReq(SELF, buf)
	// case config.CS_EquipAffixRemakeReq:
	// 	return EquipAffixRemakeReq(SELF)
	case config.CS_EquipWearReq:
		return EquipWearReq(SELF, buf)
	case config.CS_EquipJewelWearReq:
		return EquipJewelWearReq(SELF, buf)
	case config.CS_EquipComposeReq:
		return EquipComposeReq(SELF, buf)

	case config.CS_TeamRoleChangeReq:
		return TeamRoleChangeReq(SELF, buf)
	case config.CS_TeamNameChangeReq:
		return TeamNameChangeReq(SELF, buf)
	case config.CS_TeamSetActiveReq:
		return TeamSetActiveReq(SELF, buf)
	case config.CS_TeamUnlockReq:
		return TeamUnlockReq(SELF, buf)
	case config.CS_CaptainSkillUnlockReq:
		return CaptainSkillUnlockReq(SELF, buf)
	case config.CS_CaptainSkillUpgradeReq:
		return CaptainSkillUpgradeReq(SELF, buf)
	case config.CS_CaptainSkillChangeReq:
		return CaptainSkillChangeReq(SELF, buf)

	case config.CS_ShopDataReq:
		return ShopDataReq(SELF, buf)
	case config.CS_ShopBuyReq:
		return ShopBuyReq(SELF, buf)

	case config.CS_GetAllMailReq:
		return GetAllMailReq(SELF, buf)
	case config.CS_GetMailItemReq:
		return GetMailItemReq(SELF, buf)
	case config.CS_DelMailReq:
		return DelMailReq(SELF, buf)
	case config.CS_ReadMailReq:
		return ReadMailReq(SELF, buf)

	case config.CS_GetGachaInfoReq:
		return GetGachaInfoReq(SELF, buf)
	case config.CS_DoGachaReq:
		return DoGachaReq(SELF, buf)
	case config.CS_GachaWishReq:
		return GachaWishReq(SELF, buf)
	case config.CS_GachaHistoryReq:
		return GachaHistoryReq(SELF, buf)

	case config.CS_CodexRewardTakeReq:
		return CodexRewardTakeReq(SELF, buf)
	case config.CS_GetCodexRoleFightPropReq:
		return GetCodexRoleFightPropReq(SELF, buf)

	case config.CS_CREATE_BATTLE:
		return CreateBattleReq(SELF, buf)
	case config.SC_BATTLE_OVER:
		return BattleOver(SELF, buf)

	case config.CS_WeaponWearReq:
		return WeaponWearReq(SELF, buf)
	case config.CS_WeaponUpgradeReq:
		return WeaponUpgradeReq(SELF, buf)
	case config.CS_WeaponPromoteReq:
		return WeaponPromoteReq(SELF, buf)
	case config.CS_WeaponStarReq:
		return WeaponStarReq(SELF, buf)
	case config.CS_WeaponLockReq:
		return WeaponLockReq(SELF, buf)

	case config.CS_HomeDataReq:
		return HomeDataReq(SELF, buf)
	case config.CS_HomeBuildingEditReq:
		return HomeBuildingEditReq(SELF, buf)
	case config.CS_HomeFarmLandOpReq:
		return HomeFarmLandOpReq(SELF, buf)
	case config.CS_HomeFactoryOpReq:
		return HomeFactoryOpReq(SELF, buf)
	case config.CS_HomeBuildingUpgradeReq:
		return HomeBuildingUpgradeReq(SELF, buf)

	case config.CS_ActivityDataReq:
		return ActivityDataReq(SELF, buf)
	case config.CS_DungeonQuickFightReq:
		return DungeonQuickFightReq(SELF, buf)
	case config.CS_TaskRewardTakeReq:
		return TaskRewardTakeReq(SELF, buf)
	case config.CS_TaskPointRewardTakeReq:
		return TaskPointRewardTakeReq(SELF, buf)
	case config.CS_PayActivityInfoReq:
		return PayActivityInfoReq(SELF, buf)
	case config.CS_SignInRewardTakeReq:
		return SignInRewardTakeReq(SELF, buf)
	case config.CS_ZpReq:
		return ZpReq(SELF, buf)
	case config.CS_ZpBdRewardTakeReq:
		return ZpBdRewardTakeReq(SELF, buf)
	case config.CS_PayActivityTaskRewardTakeReq:
		return PayActivityTaskRewardTakeReq(SELF, buf)

	case config.CS_FishReq:
		return FishReq(SELF, buf)
	case config.CS_FishResultReq:
		return FishResultReq(SELF, buf)
	case config.CS_FishOpReq:
		return FishOpReq(SELF, buf)
	case config.CS_FishCodexReq:
		return FishCodexReq(SELF, buf)

	case config.CS_OnDayChangeReq:
		return OnDayChange(SELF, buf)

	default:
		logger.Error("invalid cmdId: %v", buf.Command)
		return config.SERVER_ERROR
	}
}

func Heart(user *sharemem.User, buf *mysock.SockBuf) int16 {
	req, ok := ParseMsg(config.CSC_Heart, new(pb.CSC_Heart), buf, user).(*pb.CSC_Heart)
	if !ok {
		return config.PROTO_ERROR
	}
	_ = req

	return SendMsg(config.CSC_Heart, &pb.CSC_Heart{
		Timenow: sharemem.MyShm.TimeNow,
	}, buf, user)
}

func ReloadConfig() error {
	logger.Info("[ReloadConfig] start")
	sharemem.ClearConfigMem()
	//err := LoadConfigData()
	//if err != nil {
	//	logger.Error("load config data err: %v", err)
	//	return err
	//}
	sharemem.InitConfigMap()
	logger.Info("[ReloadConfig] ok")
	return nil
}
